
  PROCEDURE EXPRESSION(FSYS: SETOFSYS); FORWARD;

  PROCEDURE SELECTOR(FSYS: SETOFSYS; FCP: CTP);
    VAR LATTR: ATTR; LCP: CTP; LMIN,LMAX: INTEGER;
  BEGIN
    WITH FCP^, GATTR DO
      BEGIN TYPTR := IDTYPE; KIND := VARBL;
	CASE KLASS OF
	  VARS:
	    IF VKIND = ACTUAL THEN
	      BEGIN ACCESS := DRCT; VLEVEL := VLEV;
		DPLMT := VADDR
	      END
	    ELSE
	      BEGIN
		IF VLEV = 1 THEN GEN1(39(*LDO*),VADDR)
		ELSE GEN2(54(*LOD*),LEVEL-VLEV,VADDR);
		ACCESS := INDRCT; IDPLMT := 0
	      END;
	  FIELD:
	    WITH DISPLAY[DISX] DO
	     BEGIN
	      IF OCCUR = CREC THEN
		BEGIN ACCESS := DRCT; VLEVEL := CLEV;
		  DPLMT := CDSPL + FLDADDR
		END
	      ELSE
		BEGIN
		  IF LEVEL = 1 THEN GEN1(39(*LDO*),VDSPL)
		  ELSE GEN2(54(*LOD*),0,VDSPL);
		  ACCESS := INDRCT; IDPLMT := FLDADDR
		END;
	      IF FISPACKD THEN
		BEGIN LOADADDRESS;
		  IF ((FLDRBIT = 0) OR (FLDRBIT = 8))
		        AND (FLDWIDTH = 8) THEN
		    BEGIN ACCESS := BYTE;
		      IF FLDRBIT = 8 THEN GEN1(34(*INC*),1)
		    END
		  ELSE
		    BEGIN ACCESS := PACKD;
		      GENLDC(FLDWIDTH); GENLDC(FLDRBIT)
		    END
		END
	     END;
	  FUNC:
	    IF PFDECKIND <> DECLARED THEN ERROR(150)
	    ELSE
	      IF NOT INSCOPE THEN ERROR(103)
	      ELSE
		  BEGIN ACCESS := DRCT; VLEVEL := PFLEV + 1;
		    DPLMT := LCAFTERMARKSTACK
		  END
	END (*CASE*);
	IF TYPTR <> NIL THEN
	  IF (TYPTR^.FORM <= POWER) AND
	     (TYPTR^.SIZE > PTRSIZE) THEN
	    BEGIN LOADADDRESS; ACCESS := MULTI END
      END (*WITH*);
    IF NOT (SY IN SELECTSYS + FSYS) THEN
      BEGIN ERROR(59); SKIP(SELECTSYS + FSYS) END;
    WHILE SY IN SELECTSYS DO
      BEGIN
  (*[*) IF SY = LBRACK THEN
	  BEGIN
	    REPEAT LATTR := GATTR;
	      WITH LATTR DO
		IF TYPTR <> NIL THEN
		  IF TYPTR^.FORM <> ARRAYS THEN
		    BEGIN ERROR(138); TYPTR := NIL END;
	      LOADADDRESS;
	      INSYMBOL; EXPRESSION(FSYS + [COMMA,RBRACK]);
	      LOAD;
	      IF GATTR.TYPTR <> NIL THEN
		IF GATTR.TYPTR^.FORM <> SCALAR THEN ERROR(113);
	      IF LATTR.TYPTR <> NIL THEN
		WITH LATTR.TYPTR^ DO
		  BEGIN
		    IF COMPTYPES(INXTYPE,GATTR.TYPTR) THEN
		      BEGIN
			IF (INXTYPE <> NIL) AND
			    NOT STRGTYPE(LATTR.TYPTR) THEN
			  BEGIN GETBOUNDS(INXTYPE,LMIN,LMAX);
			    IF RANGECHECK THEN
			      BEGIN GENLDC(LMIN); GENLDC(LMAX);
				GEN0(8(*CHK*))
			      END;
			    IF LMIN <> 0 THEN
			      BEGIN GENLDC(ABS(LMIN));
				IF LMIN > 0 THEN GEN0(21(*SBI*))
				ELSE GEN0(2(*ADI*))
			      END
			  END
		      END
		    ELSE ERROR(139);
		    WITH GATTR DO
		      BEGIN TYPTR := AELTYPE; KIND := VARBL;
			ACCESS := INDRCT; IDPLMT := 0;
			IF TYPTR <> NIL THEN
			  IF AISPACKD THEN
			    IF ELWIDTH = 8 THEN
			      BEGIN ACCESS := BYTE;
				IF STRGTYPE(LATTR.TYPTR) AND RANGECHECK THEN
				  GEN0(27(*IXS*))
				ELSE GEN0(2(*ADI*))
			      END
			    ELSE
			      BEGIN ACCESS := PACKD;
				GEN2(64(*IXP*),ELSPERWD,ELWIDTH)
			      END
			  ELSE
			    BEGIN GEN1(36(*IXA*),TYPTR^.SIZE);
			      IF (TYPTR^.FORM <= POWER) AND
				 (TYPTR^.SIZE > PTRSIZE) THEN
				ACCESS := MULTI
			    END
		      END
		  END
	    UNTIL SY <> COMMA;
	    IF SY = RBRACK THEN INSYMBOL ELSE ERROR(12)
	  END (*IF SY = LBRACK*)
	ELSE
  (*.*)   IF SY = PERIOD THEN
	    BEGIN
	      WITH GATTR DO
		BEGIN
		  IF TYPTR <> NIL THEN
		    IF TYPTR^.FORM <> RECORDS THEN
		      BEGIN ERROR(140); TYPTR := NIL END;
		  INSYMBOL;
		  IF SY = IDENT THEN
		    BEGIN
		      IF TYPTR <> NIL THEN
			BEGIN SEARCHSECTION(TYPTR^.FSTFLD,LCP);
			  IF LCP = NIL THEN
			    BEGIN ERROR(152); TYPTR := NIL END
			  ELSE
			    WITH LCP^ DO
			      BEGIN TYPTR := IDTYPE;
				CASE ACCESS OF
				  DRCT:   DPLMT := DPLMT + FLDADDR;
				  INDRCT: IDPLMT := IDPLMT + FLDADDR;
				  MULTI,BYTE,
				  PACKD:  ERROR(400)
				END (*CASE ACCESS*);
				IF FISPACKD THEN
				  BEGIN LOADADDRESS;
				    IF ((FLDRBIT = 0) OR (FLDRBIT = 8))
					AND (FLDWIDTH = 8) THEN
				      BEGIN ACCESS := BYTE;
					IF FLDRBIT = 8 THEN GEN1(34(*INC*),1)
				      END
				    ELSE
				      BEGIN ACCESS := PACKD;
					GENLDC(FLDWIDTH); GENLDC(FLDRBIT)
				      END
				  END;
				IF TYPTR <> NIL THEN
				  IF (TYPTR^.FORM <= POWER) AND
				     (TYPTR^.SIZE > PTRSIZE) THEN
				    BEGIN LOADADDRESS; ACCESS := MULTI END
			      END
			END;
		      INSYMBOL
		    END (*SY = IDENT*)
		  ELSE ERROR(2)
		END (*WITH GATTR*)
	    END (*IF SY = PERIOD*)
	  ELSE
  (*^*)     BEGIN
	      IF GATTR.TYPTR <> NIL THEN
		WITH GATTR,TYPTR^ DO
		  IF (FORM = POINTER) OR (FORM = FILES) THEN
		    BEGIN LOAD; KIND := VARBL;
		      ACCESS := INDRCT; IDPLMT := 0;
		      IF FORM = POINTER THEN TYPTR := ELTYPE
		      ELSE
			BEGIN TYPTR := FILTYPE;
			  IF TYPTR = NIL THEN ERROR(399)
			END;
		      IF TYPTR <> NIL THEN
			IF (TYPTR^.FORM <= POWER) AND
			   (TYPTR^.SIZE > PTRSIZE) THEN
				ACCESS := MULTI
		    END
		  ELSE ERROR(141);
	      INSYMBOL
	    END;
	IF NOT (SY IN FSYS + SELECTSYS) THEN
	  BEGIN ERROR(6); SKIP(FSYS + SELECTSYS) END
      END (*WHILE*)
  END (*SELECTOR*) ;

  PROCEDURE CALL(FSYS: SETOFSYS; FCP: CTP);
    VAR LKEY: 1..40; WASLPARENT: BOOLEAN;

    PROCEDURE VARIABLE(FSYS: SETOFSYS);
      VAR LCP: CTP;
    BEGIN
      IF SY = IDENT THEN
	BEGIN SEARCHID([FIELD,VARS],LCP); INSYMBOL END
      ELSE BEGIN ERROR(2); LCP := UVARPTR END;
      SELECTOR(FSYS,LCP)
    END (*VARIABLE*) ;

    PROCEDURE STRGVAR(FSYS: SETOFSYS; MUSTBEVAR: BOOLEAN);
    BEGIN EXPRESSION(FSYS);
      WITH GATTR DO
	IF ((KIND = CST) AND (TYPTR = CHARPTR))
	    OR STRGTYPE(TYPTR) THEN
	  IF KIND = VARBL THEN LOADADDRESS
	  ELSE
	    BEGIN
	      IF MUSTBEVAR THEN ERROR(154);
	      IF KIND = CST THEN
		BEGIN
		  IF TYPTR = CHARPTR THEN
		    BEGIN
		      WITH SCONST^ DO
			BEGIN CCLASS := STRG; SLGTH := 1;
			  SVAL[1] := CHR(CVAL.IVAL)
			END;
		      CVAL.VALP := SCONST;
		      NEW(TYPTR,ARRAYS,TRUE,TRUE);
		      TYPTR^ := STRGPTR^;
		      TYPTR^.MAXLENG := 1
		    END;
		  LOADADDRESS
		END
	    END
	ELSE
	  BEGIN
	    IF GATTR.TYPTR <> NIL THEN ERROR(125);
	    GATTR.TYPTR := STRGPTR
	  END
    END (*STRGVAR*) ;

    PROCEDURE NEWSTMT;
      LABEL 1;
      VAR LSP,LSP1: STP; VARTS,LMIN,LMAX: INTEGER;
	  LSIZE,LSZ: ADDRRANGE; LVAL: VALU;
    BEGIN VARIABLE(FSYS + [COMMA,RPARENT]); LOADADDRESS;
      LSP := NIL; VARTS := 0; LSIZE := 0;
      IF GATTR.TYPTR <> NIL THEN
	WITH GATTR.TYPTR^ DO
	  IF FORM = POINTER THEN
	    BEGIN
	      IF ELTYPE <> NIL THEN
		WITH ELTYPE^ DO
		  BEGIN LSIZE := SIZE;
		    IF FORM = RECORDS THEN LSP := RECVAR
		  END
	    END
	  ELSE ERROR(116);
      WHILE SY = COMMA DO
	BEGIN INSYMBOL;
	  CONSTANT(FSYS + [COMMA,RPARENT],LSP1,LVAL);
	  VARTS := VARTS + 1;
	  IF LSP = NIL THEN ERROR(158)
	  ELSE
	    IF LSP^.FORM <> TAGFLD THEN ERROR(162)
	    ELSE
	      IF LSP^.TAGFIELDP <> NIL THEN
		IF STRGTYPE(LSP1) OR (LSP1 = REALPTR) THEN ERROR(159)
		ELSE
		  IF COMPTYPES(LSP^.TAGFIELDP^.IDTYPE,LSP1) THEN
		    BEGIN
		      LSP1 := LSP^.FSTVAR;
		      WHILE LSP1 <> NIL DO
			WITH LSP1^ DO
			  IF VARVAL.IVAL = LVAL.IVAL THEN
			    BEGIN LSIZE := SIZE; LSP := SUBVAR;
			      GOTO 1
			    END
			  ELSE LSP1 := NXTVAR;
		      LSIZE := LSP^.SIZE; LSP := NIL;
		    END
		  ELSE ERROR(116);
    1:  END (*WHILE*) ;
      GENLDC(LSIZE);
      GEN1(30(*CSP*),1(*NEW*))
    END (*NEWSTMT*) ;

    PROCEDURE MOVE;
    BEGIN VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      IF LKEY = 27 THEN
	BEGIN EXPRESSION(FSYS + [COMMA]); LOAD END
      ELSE
	BEGIN VARIABLE(FSYS + [COMMA]); LOADADDRESS END;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      EXPRESSION(FSYS + [RPARENT]); LOAD;
      IF LKEY = 27 THEN GEN1(30(*CSP*),10(*FLC*))
      ELSE
	IF LKEY = 21 THEN GEN1(30(*CSP*),2(*MVL*))
	ELSE GEN1(30(*CSP*),3(*MVR*))
    END (*MOVE*) ;

    PROCEDURE EXIT;
      VAR LCP: CTP;
    BEGIN
      IF SY = IDENT THEN
	BEGIN SEARCHID([PROC,FUNC],LCP); INSYMBOL END
      ELSE
	IF (SY = PROGSY) THEN
	  BEGIN LCP := OUTERBLOCK; INSYMBOL END
	ELSE LCP := NIL;
      IF LCP <> NIL THEN
	IF LCP^.PFDECKIND = DECLARED THEN
	  BEGIN GENLDC(LCP^.PFSEG); GENLDC(LCP^.PFNAME) END
	ELSE ERROR(125)
      ELSE ERROR(125);
      GEN1(30(*CSP*),4(*XIT*))
    END (*EXIT*) ;

    PROCEDURE UNITIO;
    BEGIN
      IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD;
      IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF SY = COMMA THEN
	BEGIN INSYMBOL;
	  IF SY = COMMA THEN GENLDC(0)
	  ELSE
	    BEGIN
	      EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD;
	      IF GATTR.TYPTR <> INTPTR THEN ERROR(125)
	    END
	END
      ELSE GENLDC(0);
      IF SY = COMMA THEN
	BEGIN INSYMBOL;
	  EXPRESSION(FSYS + [RPARENT]); LOAD;
	  IF GATTR.TYPTR <> BOOLPTR THEN ERROR(135)
	END
      ELSE GENLDC(0);
      IF LKEY = 13 THEN GEN1(30(*CSP*),5(*URD*))
      ELSE GEN1(30(*CSP*),6(*UWT*))
    END (*UNITIO*);

    PROCEDURE CONCAT;
      VAR LLC: ADDRRANGE; TEMPLGTH: INTEGER;
    BEGIN TEMPLGTH := 0;
      LLC := LC; LC := LC + (STRGLGTH DIV CHRSPERWD) + 1;
      GENLDC(0); GEN2(56(*STR*),0,LLC);
      GEN2(50(*LDA*),0,LLC);
      REPEAT
	STRGVAR(FSYS + [COMMA,RPARENT],FALSE);
	TEMPLGTH := TEMPLGTH + GATTR.TYPTR^.MAXLENG;
	IF TEMPLGTH < STRGLGTH THEN GENLDC(TEMPLGTH)
	ELSE GENLDC(STRGLGTH);
	GEN2(77(*CXP*),0(*SYS*),23(*SCONCAT*));
	GEN2(50(*LDA*),0,LLC);
	TEST := SY <> COMMA;
	IF NOT TEST THEN INSYMBOL
      UNTIL TEST;
      IF TEMPLGTH < STRGLGTH THEN
	LC := LLC + (TEMPLGTH DIV CHRSPERWD) + 1
      ELSE TEMPLGTH := STRGLGTH;
      IF LC > LCMAX THEN LCMAX := LC;
      LC := LLC;
      WITH GATTR DO
	BEGIN NEW(TYPTR,ARRAYS,TRUE,TRUE);
	  TYPTR^ := STRGPTR^;
	  TYPTR^.MAXLENG := TEMPLGTH
	END
    END (*CONCAT*) ;

    PROCEDURE COPYDELETE;
      VAR LLC: ADDRRANGE; LSP: STP;
    BEGIN
      IF LKEY = 19 THEN
	BEGIN LLC := LC;
	  LC := LC + (STRGLGTH DIV CHRSPERWD) + 1;
	END;
      STRGVAR(FSYS + [COMMA], LKEY = 18);
      IF LKEY = 19 THEN
	BEGIN LSP := GATTR.TYPTR;
	  GEN2(50(*LDA*),0,LLC)
	END;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      EXPRESSION(FSYS + [COMMA]); LOAD;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      EXPRESSION(FSYS + [RPARENT]); LOAD;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF LKEY = 19 THEN
	BEGIN
	  GEN2(77(*CXP*),0(*SYS*),25(*SCOPY*));
	  GEN2(50(*LDA*),0,LLC);
	  IF LSP^.MAXLENG < STRGLGTH THEN
	    LC := LLC + (LSP^.MAXLENG DIV CHRSPERWD) + 1;
	  IF LC > LCMAX THEN LCMAX := LC;
	  LC := LLC; GATTR.TYPTR := LSP
	END
      ELSE GEN2(77(*CXP*),0(*SYS*),26(*SDELETE*))
    END (*COPYDELETE*) ;

    PROCEDURE CLOSE;
    BEGIN
      VARIABLE(FSYS + [COMMA,RPARENT]); LOADADDRESS;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR^.FORM <> FILES THEN ERROR(125);
      IF SY = COMMA THEN
	BEGIN INSYMBOL;
	  IF SY = IDENT THEN
	   BEGIN
	    IF ID = 'NORMAL  ' THEN GENLDC(0)
	    ELSE
	      IF ID = 'LOCK    ' THEN GENLDC(1)
	      ELSE
		IF ID = 'PURGE   ' THEN GENLDC(2)
		ELSE
		  IF ID = 'CRUNCH  ' THEN GENLDC(3)
		  ELSE ERROR(2);
	    INSYMBOL
	   END
	  ELSE ERROR(2)
	END
      ELSE GENLDC(0);
      GEN2(77(*CXP*),0(*SYS*),6(*FCLOSE*));
      IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*))
    END (*CLOSE*) ;

    PROCEDURE GETPUTETC;
    BEGIN
      VARIABLE(FSYS + [COMMA,RPARENT]); LOADADDRESS;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR^.FORM <> FILES THEN ERROR(125);
      CASE LKEY OF
	32:  BEGIN
		IF SY = COMMA THEN
		  BEGIN
		    INSYMBOL; EXPRESSION(FSYS + [RPARENT]); LOAD;
		    IF GATTR.TYPTR <> INTPTR THEN ERROR(125)
		  END
		ELSE ERROR(125);
		GEN2(77(*CXP*),0(*SYS*),9(*FSEEK*))
	     END;
	33:  GEN2(77(*CXP*),0(*SYS*),4(*FRESET*));
	34:  GEN2(77(*CXP*),0(*SYS*),7(*FGET*));
	35:  GEN2(77(*CXP*),0(*SYS*),8(*FPUT*));
	40:  BEGIN
		IF GATTR.TYPTR <> NIL THEN
		  IF GATTR.TYPTR^.FILTYPE <> CHARPTR THEN ERROR(399);
		GENLDC(12); GENLDC(0);
		GEN2(77(*CXP*),0(*SYS*),17(*WRC*))
	     END
      END (*CASE*) ;
      IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*))
    END (*GETPUTETC*) ;

    PROCEDURE SCAN;
    BEGIN
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      IF SY = RELOP THEN
	BEGIN
	  IF OP = EQOP THEN GENLDC(0)
	  ELSE
	    IF OP = NEOP THEN GENLDC(1)
	    ELSE ERROR(125);
	  INSYMBOL
	END
      ELSE ERROR(125);
      EXPRESSION(FSYS + [COMMA]); LOAD;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR <> CHARPTR THEN ERROR(125);
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      VARIABLE(FSYS + [COMMA,RPARENT]); LOADADDRESS;
      IF SY = COMMA THEN
	BEGIN INSYMBOL;
	  EXPRESSION(FSYS + [RPARENT]); LOAD
	END
      ELSE GENLDC(0);
      GEN1(30(*CSP*),11(*SCN*));
      GATTR.TYPTR := INTPTR
    END (*SCAN*) ;

    PROCEDURE BLOCKIO;
    BEGIN
      VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF GATTR.TYPTR <> NIL THEN
	IF GATTR.TYPTR^.FORM <> FILES THEN ERROR(125)
	ELSE
	  IF GATTR.TYPTR^.FILTYPE <> NIL THEN ERROR(399);
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD;
      IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
      IF SY = COMMA THEN
	BEGIN INSYMBOL;
	  EXPRESSION(FSYS + [RPARENT]); LOAD;
	  IF GATTR.TYPTR <> INTPTR THEN ERROR(125)
	END
      ELSE GENLDC(-1);
      IF LKEY = 37 THEN GENLDC(1) ELSE GENLDC(0);
      GENLDC(0); GENLDC(0);
      GEN2(77(*CXP*),0(*SYS*),28(*BLOCKIO*));
      IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*));
      GATTR.TYPTR := INTPTR
    END (*BLOCKIO*) ;

    PROCEDURE DRAWSTUFF;
      VAR I,N: INTEGER;
    BEGIN
      VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
      VARIABLE(FSYS + [COMMA]); LOADADDRESS;
      IF LKEY = 42 THEN N := 6
      ELSE N := 5;
      FOR I := 0 TO N DO
	BEGIN
	  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
	  EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD;
	  IF GATTR.TYPTR <> NIL THEN
	    IF GATTR.TYPTR <> INTPTR THEN ERROR(125)
	END;
      IF LKEY = 42 THEN N := 13
      ELSE N := 12;
      GEN1(30(*CSP*),N)
    END (*DRAWSTUFF*) ;

    PROCEDURE SIZEOF;
      VAR LCP: CTP;
    BEGIN
      IF SY = IDENT THEN
	BEGIN SEARCHID([TYPES,VARS,FIELD],LCP); INSYMBOL;
	  IF LCP^.IDTYPE <> NIL THEN
	    GENLDC(LCP^.IDTYPE^.SIZE*CHRSPERWD)
	END;
      GATTR.TYPTR := INTPTR
    END (*SIZEOF*) ;


    PROCEDURE LOADIDADDR(FCP: CTP);
    BEGIN
	WITH FCP^ DO
	  IF VKIND = ACTUAL THEN
	    IF VLEV = 1 THEN GEN1(37(*LAO*),VADDR)
	    ELSE GEN2(50(*LDA*),LEVEL-VLEV,VADDR)
	  ELSE
	    IF VLEV = 1 THEN GEN1(39(*LDO*),VADDR)
	    ELSE GEN2(54(*LOD*),LEVEL-VLEV,VADDR)
    END (*LOADIDADDR*) ;

    PROCEDURE READ;
      VAR FILEPTR,LCP: CTP;
    BEGIN FILEPTR := INPUTPTR;
      IF (SY = IDENT) AND WASLPARENT THEN
	BEGIN SEARCHID([FIELD,VARS],LCP);
	  IF LCP^.IDTYPE <> NIL THEN
	    IF LCP^.IDTYPE^.FORM = FILES THEN
	      IF LCP^.IDTYPE^.FILTYPE = CHARPTR THEN
		BEGIN INSYMBOL; FILEPTR := LCP;
		  IF NOT (SY IN [COMMA,RPARENT]) THEN ERROR(20);
		  IF SY = COMMA THEN INSYMBOL
		END
	END
      ELSE
	IF WASLPARENT THEN ERROR(2);
      IF (SY = IDENT) AND WASLPARENT THEN
	BEGIN
	  REPEAT LOADIDADDR(FILEPTR);
	    VARIABLE(FSYS + [COMMA,RPARENT]); LOADADDRESS;
	    IF GATTR.TYPTR <> NIL THEN
	      IF COMPTYPES(INTPTR,GATTR.TYPTR) THEN
		GEN2(77(*CXP*),0(*SYS*),12(*FRDI*))
	      ELSE
		IF COMPTYPES(REALPTR,GATTR.TYPTR) THEN
		  GEN2(77(*CXP*),0(*SYS*),14(*FRDR*))
		ELSE
		  IF COMPTYPES(CHARPTR,GATTR.TYPTR) THEN
		    GEN2(77(*CXP*),0(*SYS*),16(*FRDC*))
		  ELSE
		    IF STRGTYPE(GATTR.TYPTR) THEN
		      BEGIN GENLDC(GATTR.TYPTR^.MAXLENG);
			GEN2(77(*CXP*),0(*SYS*),18(*FRDS*))
		      END
		    ELSE ERROR(125);
	    IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*));
	    TEST := SY <> COMMA;
	    IF NOT TEST THEN INSYMBOL
	  UNTIL TEST
	END;
      IF LKEY = 2 THEN
	BEGIN LOADIDADDR(FILEPTR);
	  GEN2(77(*CXP*),0(*SYS*),21(*FRLN*));
	  IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*))
	END
    END (*READ*) ;

    PROCEDURE WRITE;
      VAR LSP: STP; DEFAULT: BOOLEAN;
	  FILEPTR,LCP: CTP; LEN,LMIN,LMAX: INTEGER;
    BEGIN FILEPTR := OUTPUTPTR;
      IF (SY = IDENT) AND WASLPARENT THEN
	BEGIN SEARCHID([FIELD,VARS,KONST,FUNC],LCP);
	  IF LCP^.IDTYPE <> NIL THEN
	    IF LCP^.IDTYPE^.FORM = FILES THEN
	      IF LCP^.IDTYPE^.FILTYPE = CHARPTR THEN
		BEGIN INSYMBOL; FILEPTR := LCP;
		  IF NOT (SY IN [COMMA,RPARENT]) THEN ERROR(20);
		  IF SY = COMMA THEN INSYMBOL
		END
	END;
      IF (SY IN FACBEGSYS) AND WASLPARENT THEN
	BEGIN
	  REPEAT LOADIDADDR(FILEPTR);
	    EXPRESSION(FSYS + [COMMA,COLON,RPARENT]);
	    LSP := GATTR.TYPTR;
	    IF LSP <> NIL THEN
	      IF LSP^.FORM <= SUBRANGE THEN LOAD
	      ELSE LOADADDRESS;
	    IF SY = COLON THEN
	      BEGIN INSYMBOL;
		EXPRESSION(FSYS + [COMMA,COLON,RPARENT]);
		IF GATTR.TYPTR <> NIL THEN
		  IF GATTR.TYPTR <> INTPTR THEN ERROR(20);
		LOAD; DEFAULT := FALSE
	      END
	    ELSE DEFAULT := TRUE;
	    IF LSP = INTPTR THEN
	      BEGIN IF DEFAULT THEN GENLDC(0);
		GEN2(77(*CXP*),0(*SYS*),13(*FWRI*))
	      END
	    ELSE
	      IF LSP = REALPTR THEN
		BEGIN IF DEFAULT THEN GENLDC(0);
		  IF SY = COLON THEN
		    BEGIN INSYMBOL;
		      EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD;
		      IF GATTR.TYPTR <> NIL THEN
			IF GATTR.TYPTR <> INTPTR THEN ERROR(125)
		    END
		  ELSE GENLDC(0);
		  GEN2(77(*CXP*),0(*SYS*),15(*FWRR*))
		END
	      ELSE
		IF LSP = CHARPTR THEN
		  BEGIN IF DEFAULT THEN GENLDC(0);
		    GEN2(77(*CXP*),0(*SYS*),17(*FWRC*))
		  END
		ELSE
		  IF STRGTYPE(LSP) THEN
		    BEGIN IF DEFAULT THEN GENLDC(0);
		      GEN2(77(*CXP*),0(*SYS*),19(*FWRS*))
		    END
		  ELSE
		    IF PAOFCHAR(LSP) THEN
		      BEGIN LMAX := 0;
			IF LSP^.INXTYPE <> NIL THEN
			  BEGIN GETBOUNDS(LSP^.INXTYPE,LMIN,LMAX);
			     LMAX := LMAX - LMIN + 1
			  END;
			IF DEFAULT THEN GENLDC(LMAX);
			GENLDC(LMAX);
			GEN2(77(*CXP*),0(*SYS*),20(*FWRB*))
		      END
		    ELSE ERROR(125);
	    IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*));
	    TEST := SY <> COMMA;
	    IF NOT TEST THEN INSYMBOL
	  UNTIL TEST;
	END;
      IF LKEY = 4 THEN (*WRITELN*)
	BEGIN LOADIDADDR(FILEPTR);
	  GEN2(77(*CXP*),0(*SYS*),22(*FWLN*));
	  IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*))
	END
    END (*WRITE*) ;

    PROCEDURE CALLNONSPECIAL;
      VAR NXT,LCP: CTP; LSP: STP; LB: BOOLEAN;
	  LMIN,LMAX: INTEGER;
    BEGIN
      WITH FCP^ DO
	BEGIN NXT := NEXT;
	  IF PFDECKIND = DECLARED THEN
	    IF PFKIND <> ACTUAL THEN ERROR(400)
	END;
      IF SY = LPARENT THEN
	BEGIN
	  REPEAT
	    IF NXT = NIL THEN ERROR(126);
	    INSYMBOL;
	    EXPRESSION(FSYS + [COMMA,RPARENT]);
	    IF (GATTR.TYPTR <> NIL) AND (NXT <> NIL) THEN
	      BEGIN LSP := NXT^.IDTYPE;
		IF LSP <> NIL THEN
		  BEGIN
		    IF NXT^.VKIND = ACTUAL THEN
		      IF GATTR.TYPTR^.FORM <= POWER THEN
			BEGIN LB := (GATTR.TYPTR = CHARPTR)
				    AND (GATTR.KIND = CST);
			  LOAD;
			  IF LSP^.FORM = POWER THEN
			    GEN1(32(*ADJ*),LSP^.SIZE)
			  ELSE
			  IF (LSP^.FORM = SUBRANGE)
				AND RANGECHECK THEN
			    BEGIN GENLDC(LSP^.MIN.IVAL);
			      GENLDC(LSP^.MAX.IVAL);
			      GEN0(8(*CHK*))
			    END
			  ELSE
			  IF (GATTR.TYPTR = INTPTR) AND
				COMPTYPES(LSP,REALPTR) THEN
			    BEGIN GEN0(10(*FLT*));
			      GATTR.TYPTR := REALPTR
			    END
			  ELSE
			  IF LB AND STRGTYPE(LSP) THEN
			    GATTR.TYPTR := STRGPTR
			END
		      ELSE (*FORM > POWER*)
			BEGIN LB := STRGTYPE(GATTR.TYPTR)
				    AND (GATTR.KIND = CST);
			  LOADADDRESS;
			  IF LB AND PAOFCHAR(LSP) THEN
			    IF NOT LSP^.AISSTRNG THEN
			      BEGIN GEN0(80(*S1P*));
				IF LSP^.INXTYPE <> NIL THEN
				  BEGIN
				    GETBOUNDS(LSP^.INXTYPE,LMIN,LMAX);
				    IF LMAX-LMIN+1 <> 
					GATTR.TYPTR^.MAXLENG THEN ERROR(142);
				  END;
				GATTR.TYPTR := LSP
			      END
			END
		    ELSE (*VKIND = FORMAL*)
		      IF GATTR.KIND = VARBL THEN
			BEGIN LOADADDRESS;
			  IF (LSP^.FORM=POWER) THEN
			    IF GATTR.TYPTR^.SIZE <>
				LSP^.SIZE THEN ERROR(142)
			END
		      ELSE ERROR(154);
		    IF NOT COMPTYPES(LSP,GATTR.TYPTR) THEN ERROR(142)
		  END
	      END;
	    IF NXT <> NIL THEN NXT := NXT^.NEXT
	  UNTIL SY <> COMMA;
	  IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
	END (*LPARENT*) ;
      IF NXT <> NIL THEN ERROR(126);
      WITH FCP^ DO
	IF PFDECKIND = DECLARED THEN
	  BEGIN
	    IF KLASS = FUNC THEN
	      BEGIN GENLDC(0); GENLDC(0) END;
	    IF PFSEG <> SEG THEN GEN2(77(*CXP*),PFSEG,PFNAME)
	    ELSE
	      IF PFLEV = 0 THEN GEN1(66(*CBP*),PFNAME)
	      ELSE
		IF PFLEV = LEVEL THEN GEN1(78(*CLP*),PFNAME)
		ELSE
	  	IF PFLEV = 1 THEN GEN1(79(*CGP*),PFNAME)
	  	ELSE GEN1(46(*CIP*),PFNAME)
	  END
	ELSE
	  IF (CSPNUM <> 21) AND (CSPNUM <> 22) THEN
	    GEN1(30(*CSP*),CSPNUM);
      GATTR.TYPTR := FCP^.IDTYPE
    END (*CALLNONSPECIAL*) ;

  BEGIN (*CALL*)
    IF FCP^.PFDECKIND = SPECIAL THEN
      BEGIN WASLPARENT := TRUE; LKEY := FCP^.KEY;
	IF SY = LPARENT THEN INSYMBOL
	ELSE
	  IF LKEY IN [2,4,5,6] THEN WASLPARENT := FALSE
	  ELSE ERROR(9);
	IF LKEY IN [7,8,9,10,11,13,14,25,36] THEN
	  BEGIN EXPRESSION(FSYS + [COMMA,RPARENT]); LOAD END;
	CASE LKEY OF
	   1,2: READ;
	   3,4: WRITE;
	   5,6: BEGIN (*EOF & EOLN*)
		  IF WASLPARENT THEN
		    BEGIN VARIABLE(FSYS + [RPARENT]); LOADADDRESS;
		      IF GATTR.TYPTR <> NIL THEN
		        IF GATTR.TYPTR^.FORM <> FILES THEN ERROR(125)
		        ELSE
		          IF (GATTR.TYPTR^.FILTYPE <> CHARPTR) AND
			      (LKEY = 6) THEN ERROR(399)
		    END
		  ELSE
		    LOADIDADDR(INPUTPTR);
		  GENLDC(0); GENLDC(0);
		  IF LKEY = 5 THEN GEN2(77(*CXP*),0(*SYS*),10(*FEOF*))
		  ELSE GEN2(77(*CXP*),0(*SYS*),11(*FEOLN*));
		  GATTR.TYPTR := BOOLPTR
		END (*EOF*) ;
	   7,8: BEGIN GENLDC(1); (*PREDSUCC*)
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR^.FORM = SCALAR THEN
		      IF LKEY = 8 THEN GEN0(2(*ADI*))
		      ELSE GEN0(21(*SBI*))
		    ELSE ERROR(115)
		END (*PREDSUCC*) ;
	     9: BEGIN (*ORD*)
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR^.FORM >= POWER THEN ERROR(125);
		  GATTR.TYPTR := INTPTR
		END (*ORD*) ;
	    10: BEGIN (*SQR*)
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR = INTPTR THEN GEN0(24(*SQI*))
		    ELSE
		      IF GATTR.TYPTR = REALPTR THEN GEN0(25(*SQR*))
		      ELSE BEGIN ERROR(125); GATTR.TYPTR := INTPTR END
		END (*SQR*) ;
	    11: BEGIN (*ABS*)
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR = INTPTR THEN GEN0(0(*ABI*))
		    ELSE
		      IF GATTR.TYPTR = REALPTR THEN GEN0(1(*ABR*))
		      ELSE BEGIN ERROR(125); GATTR.TYPTR := INTPTR END
		END (*ABS*) ;
	    12: NEWSTMT;
	 13,14: UNITIO;
	    15: CONCAT;
	    16: BEGIN (*LENGTH*)
		  STRGVAR(FSYS + [RPARENT],FALSE);
		  GEN0(62(*LDB*)); GATTR.TYPTR := INTPTR
		END (*LENGTH*) ;
	    17: BEGIN (*INSERT*)
		  STRGVAR(FSYS + [COMMA],FALSE);
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  STRGVAR(FSYS + [COMMA],TRUE);
		  GENLDC(GATTR.TYPTR^.MAXLENG);
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  EXPRESSION(FSYS + [RPARENT]); LOAD;
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
		  GEN2(77(*CXP*),0(*SYS*),24(*SINSERT*))
		END (*INSERT*) ;
	 18,19: COPYDELETE;
	    20: BEGIN (*POS*)
		  STRGVAR(FSYS + [COMMA],FALSE);
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  STRGVAR(FSYS + [RPARENT],FALSE);
		  GENLDC(0); GENLDC(0);
		  GEN2(77(*CXP*),0(*SYS*),27(*SPOS*));
		  GATTR.TYPTR := INTPTR
		END (*POS*) ;
      27,21,22: MOVE;
	    23: EXIT;
	    24: BEGIN (*IDSEARCH*)
		  VARIABLE(FSYS + [COMMA]); LOADADDRESS;
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  VARIABLE(FSYS + [RPARENT]); LOADADDRESS;
		  GEN1(30(*CSP*),7(*IDS*))
		END (*IDSEARCH*) ;
	    25: BEGIN (*TREESEARCH*)
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  VARIABLE(FSYS + [COMMA]); LOADADDRESS;
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  VARIABLE(FSYS + [RPARENT]); LOADADDRESS;
		  GATTR.TYPTR := INTPTR;
		  GEN1(30(*CSP*),8(*TRS*))
		END (*TREESEARCH*) ;
	    26: BEGIN (*TIME*)
		  VARIABLE(FSYS + [COMMA]); LOADADDRESS;
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  VARIABLE(FSYS + [RPARENT]); LOADADDRESS;
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR <> INTPTR THEN ERROR(125);
		  GEN1(30(*CSP*),9(*TIM*))
		END (*TIME*) ;
      28,29,30: BEGIN (*OPEN*)
		  VARIABLE(FSYS + [COMMA]); LOADADDRESS;
		  IF GATTR.TYPTR <> NIL THEN
		    IF GATTR.TYPTR^.FORM <> FILES THEN ERROR(125);
		  IF SY = COMMA THEN INSYMBOL ELSE ERROR(20);
		  STRGVAR(FSYS + [RPARENT],FALSE);
		  IF LKEY = 28 THEN GENLDC(0)
		  ELSE GENLDC(1);
		  GENLDC(0); GEN2(77(*CXP*),0(*SYS*),5(*FOPEN*));
		  IF IOCHECK THEN GEN1(30(*CSP*),0(*IOC*))
		END (*OPEN*) ;
	    31: CLOSE;
32,33,34,35,40: GETPUTETC;
	    36: SCAN;
	 37,38: BLOCKIO;
	 39,42: DRAWSTUFF;
	    41: SIZEOF
	END (*SPECIAL CASES*) ;
	IF WASLPARENT THEN
	  IF SY = RPARENT THEN INSYMBOL ELSE ERROR(4)
      END (*SPECIAL PROCEDURES AND FUNCTIONS*)
    ELSE CALLNONSPECIAL
  END (*CALL*) ;
